<template>
    <div id="mapContainer" class="map-container"></div>
</template>

<script lang="ts" setup>
import { defineProps, defineEmits, computed, watch, nextTick, onBeforeMount, onMounted, onActivated, onDeactivated, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router';
import { Marker, Label, Circle, MapvglPoint, MapvglPointData, MapvglIcon, MapvglIconData, MapvglLabel, MapvglLabelData, MapvglHeatmap, MapvglHeatmapData } from './types';
import MapglMgr from './MapglMgr'
import { ref } from 'vue';
import { getCurrentInstance } from 'vue';
import { toRefs } from 'vue';


const props = defineProps({
    config: {
        type: Object,
        default: () => {
            return {
                city: {},
                center: {
                    lng: 0,
                    lat: 0,
                },
                zoom: 5,
                minZoom: 5,
                maxZoom: 18,
                panBy: {
                    x: 0,
                    y: 0,
                },
                mapvgl: {
                    pointLayerShow: true,
                    iconLayerShow: true,
                    labelLayerShow: true,
                    heatmapLayerShow: true,
                    isDynamicPointLayers: false,
                    isDynamicIconLayers: false,
                    isDynamicLabelLayers: false,
                    isDynamicHeatmapLayers: false,
                },
                isDynamicShowOverlays: false,
            };
        },
    },
    data: {
        type: Object,
        default: () => {
            return {
                markers: [] as Array<Marker>,
                labels: [] as Array<Label>,
                circles: [] as Array<Circle>,
                mapvglPoints: [] as Array<MapvglPoint>,
                mapvglIcons: [] as Array<MapvglIcon>,
                mapvglLabels: [] as Array<MapvglLabel>,
                mapvglHeatmap: {
                    options: {},
                    data: [] as Array<MapvglHeatmapData>,
                } as MapvglHeatmap,
            };
        },
    },
    callbacks: {
        type: Object,
        default: () => {
            return {
                load: () => { },
                tilesloaded: () => { },
                touchstart: () => { },
                touchmove: () => { },
                touchend: () => { },
                movestart: () => { },
                moving: () => { },
                moveend: () => { },
                zoomstart: () => { },
                zoomend: () => { },
                onLocationChange: () => { },
                onMarkerClick: () => { },
                onLabelClick: () => { },
                onMapvglPointClick: () => { },
                onMapvglIconClick: () => { },
                onMapvglLabelClick: () => { },
            }
        }
    }
});


const { config, data, callbacks } = toRefs(props);
const emit = defineEmits([
    'load',
    'tilesloaded',
    'touchstart',
    'touchmove',
    'touchend',
    'movestart',
    'moving',
    'moveend',
    'zoomstart',
    'zoomend',
    'onLocationChange',

    'onMarkerClick',
    'onLabelClick',
    'onMapvglPointClick',
    'onMapvglIconClick',
    'onMapvglLabelClick',
]);
const router = useRouter();

// const isHeatMap = false;
const defaultZoom = 15;
// const { BMap } = window as any;
let map = null;
let mapvglView = null;
let centerPoint = {};
let centerPixel = {
    x: 0,
    y: 0,
};
let minPixel = {
    x: 0,
    y: 0,
};
let maxPixel = {
    x: 0,
    y: 0,
};
let isMapTouch = <boolean>false;
let isMultiFingerTouch = <boolean>false; // 是否多指触摸
let isAllowMapDrag = <boolean>true; // 是否允许地图拖拽
let mapTouchStartPageX = <number>0;
let mapTouchStartPageY = <number>0;
let mapTouchEndPageX = <number>0;
let mapTouchEndPageY = <number>0;
let markerArr = [];
let labelArr = [] as Array<Label>;
let circleArr = [];
let mapvglPointLayerArr = [];
let mapvglIconLayerArr = [];
let mapvglLabelLayerArr = [];
let mapvglHeatmapLayer = null;
const overlayArr = computed(() => {
    return markerArr.concat(labelArr, circleArr);
});

watch(() => config.value.city, () => {
    map.centerAndZoom(config.value.city, config.value.zoom);
});
watch(() => config.value.center, () => {
    const currentZoom = map.getZoom();
    const mapPoint = new BMap.Point(config.value.center.lng, config.value.center.lat);
    map.panTo(mapPoint);
    if (currentZoom === config.value.zoom) {
        map.panTo(mapPoint);
    } else {
        map.centerAndZoom(mapPoint, config.value.zoom);
    }
    centerPoint = mapPoint;
});
watch(() => config.value.zoom, () => {
    map.setZoom(config.value.zoom);
});
watch(() => config.value.minZoom, () => {
    map.setMinZoom(config.value.minZoom);
});
watch(() => config.value.maxZoom, () => {
    map.setMaxZoom(config.value.maxZoom);
});
watch(
    () => config.value.panBy,
    () => {
        map.panBy(config.value.panBy.x, config.value.panBy.y);
    },
    {
        deep: true,
    },
);
watch(() => config.value.mapvgl.pointLayerShow, () => {
    if (config.value.mapvgl.pointLayerShow) {
        showMapvglLayers(mapvglPointLayerArr);
    } else {
        hideMapvglLayers(mapvglPointLayerArr);
    }
});
watch(() => config.value.mapvgl.iconLayerShow, () => {
    if (config.value.mapvgl.iconLayerShow) {
        showMapvglLayers(mapvglIconLayerArr);
    } else {
        hideMapvglLayers(mapvglIconLayerArr);
    }
});
watch(() => config.value.mapvgl.labelLayerShow, () => {
    if (config.value.mapvgl.labelLayerShow) {
        showMapvglLayers(mapvglLabelLayerArr);
    } else {
        hideMapvglLayers(mapvglLabelLayerArr);
    }
});
watch(() => config.value.mapvgl.heatmapLayerShow, () => {
    if (config.value.mapvgl.heatmapLayerShow) {
        mapvglView.showLayer(mapvglHeatmapLayer);
    } else {
        mapvglView.hideLayer(mapvglHeatmapLayer);
    }
});
watch(
    () => data.value.markers,
    () => {
        removeMarkers(markerArr);
        markerArr = [];
        drawMarkers();
    },
    {
        deep: true,
    },
);
watch(
    () => data.value.labels,
    () => {
        removeLabels(labelArr);
        labelArr = [];
        nextTick(() => {
            drawLabels(data.value.labels);
        });

        // if (!data.value.labels.length) {
        //     removeLabels(labelArr);
        //     labelArr = [];
        //     return;
        // }
        // let addLabelArr = [] as Array<Label>;
        // let removeMapLabelArr = [];
        // let showMapLabelArr = [];
        // let hideMapLabelArr = [];
        // for (let i = 0; i < data.value.labels.length; i++) {
        //     const label = data.value.labels[i];
        //     const findMapLabel = labelArr.find((mapLabel) => {
        //         return mapLabel.point.lng === label.point.lng && mapLabel.point.lat === label.point.lat;
        //     });
        //     if (label.state === 'add') {
        //         addLabelArr.push(label);
        //     }
        //     if (label.state === 'remove') {
        //         removeMapLabelArr.push(findMapLabel);
        //     }
        //     if (label.state === 'show') {
        //         showMapLabelArr.push(findMapLabel);
        //     }
        //     if (label.state === 'hide') {
        //         hideMapLabelArr.push(findMapLabel);
        //     }
        // }
        // if (addLabelArr.length) {
        //     drawLabels(addLabelArr);
        // }
        // if (removeMapLabelArr.length) {
        //     removeLabels(removeMapLabelArr);
        // }
        // if (showMapLabelArr.length) {
        //     showOverlays(showMapLabelArr);
        // }
        // if (hideMapLabelArr.length) {
        //     hideOverlays(hideMapLabelArr);
        // }

        // removeLabels(labelArr);
        // labelArr = [];
        // drawLabels(labelArr);
    },
    {
        deep: true,
    },
);
watch(
    () => data.value.circles,
    () => {
        removeCircles(circleArr);
        circleArr = [];
        drawCircles();
    },
    {
        deep: true,
    },
);
watch(
    () => data.value.mapvglPoints,
    () => {
        removeMapvglLayers(mapvglPointLayerArr);
        mapvglPointLayerArr = [];
        drawMapvglPointLayers();
    },
    {
        deep: true,
    },
);
watch(
    () => data.value.mapvglIcons,
    () => {
        removeMapvglLayers(mapvglIconLayerArr);
        mapvglIconLayerArr = [];
        drawMapvglIconLayers();
    },
    {
        deep: true,
    },
);
watch(
    () => data.value.mapvglLabels,
    () => {
        removeMapvglLayers(mapvglLabelLayerArr);
        mapvglLabelLayerArr = [];
        drawMapvglLabelLayers();
    },
    {
        deep: true,
    },
);
watch(
    () => data.value.mapvglHeatmap,
    () => {
        mapvglView.removeLayer(mapvglHeatmapLayer);
        mapvglHeatmapLayer = null;
        drawMapvglHeatmapLayer();
    },
    {
        deep: true,
    },
);

const load = () => {
    // Toast.allowMultiple();
    // Toast.loading({
    //     message: '加载中....',
    //     forbidClick: true,
    //     duration: 0, // 持续展示 toast
    // });
    centerPoint = map.getCenter();
    centerPixel = map.pointToPixel(centerPoint);
    minPixel = {
        x: -(centerPixel.x),
        y: -(centerPixel.y),
    };
    maxPixel = {
        x: centerPixel.x * 3,
        y: centerPixel.y * 3,
    };
    emit('load');
    callbacks.value.load && callbacks.value.load()
};
const tilesloaded = () => {
    callbacks.value.tilesloaded && callbacks.value.tilesloaded()
    emit('tilesloaded');
};
const touchstart = (e) => {
    const touch = e.changedTouches[0];
    mapTouchStartPageX = touch.pageX;
    mapTouchStartPageY = touch.pageY;
    if (e.touches.length > 1) {
        isMultiFingerTouch = true;
    } else {
        isMultiFingerTouch = false;
    }
    emit('touchstart', e);
    callbacks.value.touchstart && callbacks.value.touchstart()
};
const touchmove = (e) => {
    emit('touchmove', e);
    callbacks.value.touchmove && callbacks.value.touchmove(e)
};
const touchend = (e) => {
    const touch = e.changedTouches[0];
    mapTouchEndPageX = touch.pageX;
    mapTouchEndPageY = touch.pageY;
    const mapTouchPageX = Math.abs(mapTouchEndPageX - mapTouchStartPageX);
    const mapTouchPageY = Math.abs(mapTouchEndPageY - mapTouchStartPageY);
    if (mapTouchPageX > 10 || mapTouchPageY > 10) {
        isMapTouch = true;
    } else {
        isMapTouch = false;
    }
    setMapvglLayersData();
    emit('touchend', {
        e: e,
        zoom: map.getZoom(),
        isMultiFingerTouch: isMultiFingerTouch,
    });
    isMultiFingerTouch = false;
    callbacks.value.touchend && callbacks.value.touchend({
        e: e,
        zoom: map.getZoom(),
        isMultiFingerTouch: isMultiFingerTouch,
    })
};
const movestart = () => {
    emit('movestart');
    callbacks.value.movestart && callbacks.value.movestart()
};
const moving = () => {
    emit('moving');
    callbacks.value.moving && callbacks.value.moving()
};
const moveend = () => {
    centerPoint = map.getCenter();
    dynamicShowOverlays();
    emit('moveend');
    callbacks.value.moveend && callbacks.value.moveend()
};
const zoomstart = () => {
    emit('zoomstart', map.getZoom());
    callbacks.value.zoomstart && callbacks.value.zoomstart(map.getZoom())
};
const zoomend = () => {
    dynamicShowOverlays();
    setMapvglLayersData();
    emit('zoomend', { zoom: map.getZoom(), center: map.getCenter() });
    callbacks.value.zoomend && callbacks.value.zoomend({ zoom: map.getZoom(), center: map.getCenter() })

};

// Mapvgl是一款地理信息可视化开源库，可以用来展示大量地理信息数据，点、线、面的数据，每种数据也有不同的展示类型，如直接打点、热力图、网格、聚合等方式展示数据
const loadMapvgl = () => {
    const script = document.createElement('script');
    script.src = 'https://unpkg.com/mapvgl@1.0.0-beta.168/dist/mapvgl.min.js';
    script.onload = () => {
        mapvglView = new mapvgl.View({
            map: map,
            mapType: 'bmap',
        });
    };
    document.body.appendChild(script);
};


const initMap = async () => {

    map = MapglMgr.Instance().getMapInstance(BMap);
    // map = new BMap.Map('mapContainer');

    // console.log('config', config.value);
    if (config.value.city) {
        map.centerAndZoom(config.value.city, config.value.zoom);
    } else {
        const localCity = await new BMap.LocalCity();
        localCity.get((localCityData) => {
            map.centerAndZoom(localCityData.center, config.value.zoom);
        });
    }

    map.setMinZoom(config.value.minZoom);
    map.setMaxZoom(config.value.maxZoom);
    map.highResolutionEnabled(); // 使用高分辨率底图
    map.enableScrollWheelZoom(); // 开启鼠标滚轮缩放功能，仅对PC上有效
    // map.enableInertialDragging(); // 启用地图惯性拖拽
    map.enableContinuousZoom(); // 启用连续缩放效果
    map.disableDoubleClickZoom(); // 禁用双击放大
    // map.disableRotateGestures(); // 禁用通过手势旋转地图
    map.addEventListener('load', load); // 调用Map.centerAndZoom()方法时会触发此事件。这表示位置、缩放层级已经确定，但可能还在载入地图图块
    map.addEventListener('tilesloaded', tilesloaded); // 当地图所有图块完成加载时触发此事件
    map.addEventListener('touchstart', touchstart); // 触摸开始时触发此事件，仅适用移动设备
    map.addEventListener('touchmove', touchmove); // 触摸移动时触发此事件，仅适用移动设备
    map.addEventListener('touchend', touchend); // 触摸结束时触发此事件，仅适用移动设备
    map.addEventListener('movestart', movestart); // 地图移动开始时触发此事件
    map.addEventListener('moving', moving); // 地图移动过程中触发此事件
    map.addEventListener('moveend', moveend); // 地图移动结束时触发此事件
    map.addEventListener('zoomstart', zoomstart); // 地图更改缩放级别开始时触发触发此事件
    map.addEventListener('zoomend', zoomend); // 地图更改缩放级别结束时触发触发此事件

    // mapvglView = new mapvgl.View({
    //     map: map,
    //     mapType: 'bmap',
    // });

    mapvglView = MapglMgr.Instance().getMapGlInstance(mapvgl, map);
    drawMapvglHeatmapLayer();
    console.log('mapvglView', mapvglView);

    //loadMapvgl();
};
const loadMap = () => {
    const script = document.createElement('script');
    // script.src = 'https://api.map.baidu.com/api?v=1.0&type=webgl&ak=pMKZ5LA04gnwycQQm3MHxypWV30aHDLI&callback=initMap';
    script.src = 'https://api.map.baidu.com/api?v=1.0&type=webgl&ak=nffLoXGswmus5QtOgQYma9DE8LQMPnUi&callback=initMap';
    // 异步加载百度地图API完成之后，使用"callback"来触发初始化地图的回调函数
    window.initMap = initMap; // 因为callback触发的是window上的方法，所以需要将初始化地图的方法绑定在window上
    document.body.appendChild(script);
};

const drawMarkers = () => {
    for (let i = 0; i < data.value.markers.length; i++) {
        const marker = data.value.markers[i];
        const mapPoint = new BMap.Point(marker.point.lng, marker.point.lat);
        const mapMarker = new BMap.Marker(mapPoint, marker.options);
        if (marker.icon) {
            const markerIconSize = new BMap.Size(marker.icon.width, marker.icon.height);
            const markerIcon = new BMap.Icon(marker.icon.url, markerIconSize, marker.icon.options);
            mapMarker.setIcon(markerIcon);
        }
        if (marker.label) {
            const markerLabelOptions = {
                position: new BMap.Point(marker.label.point.lng, marker.label.point.lat),
                ...marker.label.options,
            };
            const markerLabel = new BMap.Label(marker.label.content, markerLabelOptions);
            markerLabel.setStyle(marker.label.style);
            mapMarker.setLabel(markerLabel);
        }
        mapMarker.addEventListener('click', () => {
            emit('onMarkerClick', marker);
            callbacks.value.onMarkerClick && callbacks.value.onMarkerClick(marker)
        });
        map.addOverlay(mapMarker);
        markerArr.push(mapMarker);
    };
};
const removeMarkers = (markerArr) => {
    for (let i = 0; i < markerArr.length; i++) {
        const marker = markerArr[i];
        map.removeOverlay(marker);
    }
};
const drawLabels = (addLabelArr: Array<Label>) => {
    for (let i = 0; i < addLabelArr.length; i++) {
        const label = addLabelArr[i];
        const labelOptions = {
            position: new BMap.Point(label.point.lng, label.point.lat),
            ...label.options,
        };
        const mapLabel = new BMap.Label(label.content, labelOptions);
        mapLabel.setStyle(label.style);
        mapLabel.addEventListener('click', () => {
            emit('onLabelClick', label);
            callbacks.value.onLabelClick && callbacks.value.onLabelClick(label)

        });
        map.addOverlay(mapLabel);
        labelArr.push(mapLabel);
    };
};
const removeLabels = (mapLabelArr) => {
    for (let i = 0; i < mapLabelArr.length; i++) {
        const mapLabel = mapLabelArr[i];
        map.removeOverlay(mapLabel);
        labelArr = labelArr.filter((existMapLabel) => {
            return !existMapLabel.point.equals(mapLabel.point);
        });
    }
};
const showOverlays = (overlayArr) => {
    for (let i = 0; i < overlayArr.length; i++) {
        const overlay = overlayArr[i];
        overlay.show();
    }
};
const hideOverlays = (overlayArr) => {
    for (let i = 0; i < overlayArr.length; i++) {
        const overlay = overlayArr[i];
        overlay.hide();
    }
};
const dynamicShowOverlays = () => {
    if (config.value.isDynamicShowOverlays) {
        return;
    }
    // 当地图上overlay过多时，为了避免地图崩掉，动态显示地图上的overlay
    if (overlayArr.value.length < 10) {
        return;
    }
    for (let i = 0; i < overlayArr.value.length; i++) {
        const overlay = overlayArr.value[i];
        const overlayPixel = map.pointToPixel(overlay.point);
        if (overlayPixel.x < minPixel.x) {
            overlay.hide();
            continue;
        }
        if (overlayPixel.x > maxPixel.x) {
            overlay.hide();
            continue;
        }
        if (overlayPixel.y < minPixel.y) {
            overlay.hide();
            continue;
        }
        if (overlayPixel.y > maxPixel.y) {
            overlay.hide();
            continue;
        }
        overlay.show();
    }
};
const drawCircles = () => {
    for (let i = 0; i < data.value.circles.length; i++) {
        const circle = data.value.circles[i];
        const mapPoint = new BMap.Point(circle.point.lng, circle.point.lat);
        const mapCircle = new BMap.Circle(mapPoint, circle.radius, circle.options);
        map.addOverlay(mapCircle);
        circleArr.push(mapCircle);
    };
};
const removeCircles = (circleArr) => {
    for (let i = 0; i < circleArr.length; i++) {
        const circle = circleArr[i];
        map.removeOverlay(circle);
    }
};
const setMapvglPointLayersData = () => {
    for (let i = 0; i < mapvglPointLayerArr.length; i++) {
        const mapvglPoint = data.value.mapvglPoints[i];
        const mapvglPointLayer = mapvglPointLayerArr[i];
        let mapvglPointDataShow = mapvglPoint.data;
        if (config.value.mapvgl.isDynamicPointLayers) {
            mapvglPointDataShow = mapvglPoint.data.filter((mapvglPointData: MapvglPointData) => {
                const mapvglPoint = new BMap.Point(mapvglPointData.lng, mapvglPointData.lat);
                const mapvglPointPixel = map.pointToPixel(mapvglPoint);
                if (mapvglPointPixel.x < minPixel.x) {
                    return false;
                }
                if (mapvglPointPixel.x > maxPixel.x) {
                    return false;
                }
                if (mapvglPointPixel.y < minPixel.y) {
                    return false;
                }
                if (mapvglPointPixel.y > maxPixel.y) {
                    return false;
                }
                return true;
            });
        }
        const mapvglPointLayerData = mapvglPointDataShow.map((mapvglPointData: MapvglPointData) => {
            return {
                geometry: {
                    type: 'Point',
                    coordinates: [mapvglPointData.lng, mapvglPointData.lat],
                },
                mapvglPointData: mapvglPointData,
            };
        });
        mapvglPointLayer.setData(mapvglPointLayerData);
    };
};
const drawMapvglPointLayers = () => {
    console.error('draw：pointLayer')
    for (let i = 0; i < data.value.mapvglPoints.length; i++) {
        const mapvglPoint = data.value.mapvglPoints[i];
        const mapvglPointLayer = new mapvgl.PointLayer({
            ...mapvglPoint.options,
            enablePicked: true, // 是否可以拾取
            blend: 'lighter', // 颜色叠加模式
            onClick: (e) => { // 点击事件
                if (isMapTouch || isMultiFingerTouch) {
                    return;
                }
                if (!e.dataItem) {
                    return;
                }
                emit('onMapvglPointClick', e);
                callbacks.value.onMapvglPointClick && callbacks.value.onMapvglPointClick(e)

            },
        });
        mapvglView.addLayer(mapvglPointLayer);
        mapvglPointLayerArr.push(mapvglPointLayer);
        setMapvglPointLayersData();
    };
};
const setMapvglIconLayersData = () => {
    for (let i = 0; i < mapvglIconLayerArr.length; i++) {
        const mapvglIcon = data.value.mapvglIcons[i];
        const mapvglIconLayer = mapvglIconLayerArr[i];
        let mapvglIconDataShow = mapvglIcon.data;
        if (config.value.mapvgl.isDynamicIconLayers) {
            mapvglIconDataShow = mapvglIcon.data.filter((mapvglIconData: MapvglIconData) => {
                const mapvglIconPoint = new BMap.Point(mapvglIconData.lng, mapvglIconData.lat);
                const mapvglIconPixel = map.pointToPixel(mapvglIconPoint);
                if (mapvglIconPixel.x < minPixel.x) {
                    return false;
                }
                if (mapvglIconPixel.x > maxPixel.x) {
                    return false;
                }
                if (mapvglIconPixel.y < minPixel.y) {
                    return false;
                }
                if (mapvglIconPixel.y > maxPixel.y) {
                    return false;
                }
                return true;
            });
        }
        const mapvglIconLayerData = mapvglIconDataShow.map((mapvglIconData: MapvglIconData) => {
            return {
                geometry: {
                    type: 'Point',
                    coordinates: [mapvglIconData.lng, mapvglIconData.lat],
                },
                mapvglIconData: mapvglIconData,
            };
        });
        mapvglIconLayer.setData(mapvglIconLayerData);
    };
};
const drawMapvglIconLayers = () => {
    console.error('draw iconLayer')
    for (let i = 0; i < data.value.mapvglIcons.length; i++) {
        const mapvglIcon = data.value.mapvglIcons[i];
        const mapvglIconLayer = new mapvgl.IconLayer({
            width: mapvglIcon.width,
            height: mapvglIcon.height,
            icon: mapvglIcon.img,
            enablePicked: true, // 是否可以拾取
            blend: 'lighter', // 颜色叠加模式
            onClick: (e) => { // 点击事件
                if (isMapTouch || isMultiFingerTouch) {
                    return;
                }
                if (!e.dataItem) {
                    return;
                }
                emit('onMapvglIconClick', e);
                callbacks.value.onMapvglIconClick && callbacks.value.onMapvglIconClick(e)

            },
        });
        mapvglView.addLayer(mapvglIconLayer);
        mapvglIconLayerArr.push(mapvglIconLayer);
        setMapvglIconLayersData();

    };
};
const setMapvglLabelLayersData = () => {
    for (let i = 0; i < mapvglLabelLayerArr.length; i++) {
        const mapvglLabel = data.value.mapvglLabels[i];
        const mapvglLabelLayer = mapvglLabelLayerArr[i];
        let mapvglLabelDataShow = mapvglLabel.data;
        if (config.value.mapvgl.isDynamicLabelLayers) {
            mapvglLabelDataShow = mapvglLabel.data.filter((mapvglLabelData: MapvglLabelData) => {
                const mapvglLabelPoint = new BMap.Point(mapvglLabelData.lng, mapvglLabelData.lat);
                const mapvglLabelPixel = map.pointToPixel(mapvglLabelPoint);
                if (mapvglLabelPixel.x < minPixel.x) {
                    return false;
                }
                if (mapvglLabelPixel.x > maxPixel.x) {
                    return false;
                }
                if (mapvglLabelPixel.y < minPixel.y) {
                    return false;
                }
                if (mapvglLabelPixel.y > maxPixel.y) {
                    return false;
                }
                return true;
            });
        }
        const mapvglLabelLayerData = mapvglLabelDataShow.map((mapvglLabelData: MapvglLabelData) => {
            return {
                geometry: {
                    type: 'Point',
                    coordinates: [mapvglLabelData.lng, mapvglLabelData.lat]
                },
                properties: {
                    text: mapvglLabelData.text,
                },
                mapvglLabelData: mapvglLabelData,
            };
        });
        mapvglLabelLayer.setData(mapvglLabelLayerData);
    };
};
const drawMapvglLabelLayers = () => {
    console.error('draw labelLayer')

    for (let i = 0; i < data.value.mapvglLabels.length; i++) {
        const mapvglLabel = data.value.mapvglLabels[i];
        let mapvglLabelOptions = {
            collides: true, // 是否开启碰撞检测, 数量较多时建议打开
            enablePicked: true,
            ...mapvglLabel.options,
            onClick: (e) => {
                if (isMapTouch || isMultiFingerTouch) {
                    return;
                }
                if (!e.dataItem) {
                    return;
                }
                emit('onMapvglLabelClick', e);
                callbacks.value.onMapvglLabelClick && callbacks.value.onMapvglLabelClick(e)

            },
        };
        const mapvglLabelLayer = new mapvgl.LabelLayer(mapvglLabelOptions);
        mapvglView.addLayer(mapvglLabelLayer);
        mapvglLabelLayerArr.push(mapvglLabelLayer);
        setMapvglLabelLayersData();
    };
};
const showMapvglLayers = (mapvglLayerArr) => {
    for (let i = 0; i < mapvglLayerArr.length; i++) {
        const mapvglLayer = mapvglLayerArr[i];
        mapvglView.showLayer(mapvglLayer);
    };
};
const hideMapvglLayers = (mapvglLayerArr) => {
    for (let i = 0; i < mapvglLayerArr.length; i++) {
        const mapvglLayer = mapvglLayerArr[i];
        mapvglView.hideLayer(mapvglLayer);
    };
};
const removeMapvglLayers = (mapvglLayerArr) => {
    for (let i = 0; i < mapvglLayerArr.length; i++) {
        const mapvglLayer = mapvglLayerArr[i];
        mapvglView.removeLayer(mapvglLayer);
    };
};
const setMapvglHeatmapLayerData = () => {

    console.log('draw热力图', data.value.mapvglHeatmap.data);

    let mapvglHeatmapDataShow = data.value.mapvglHeatmap.data;
    if (config.value.mapvgl.isDynamicHeatmapLayers) {
        mapvglHeatmapDataShow = data.value.mapvglHeatmap.data.filter((mapvglHeatmapData: MapvglHeatmapData) => {
            const mapvglHeatmapPoint = new BMap.Point(mapvglHeatmapData.lng, mapvglHeatmapData.lat);
            const mapvglHeatmapPixel = map.pointToPixel(mapvglHeatmapPoint);
            if (mapvglHeatmapPixel.x < minPixel.x) {
                return false;
            }
            if (mapvglHeatmapPixel.x > maxPixel.x) {
                return false;
            }
            if (mapvglHeatmapPixel.y < minPixel.y) {
                return false;
            }
            if (mapvglHeatmapPixel.y > maxPixel.y) {
                return false;
            }
            return true;
        });
    }
    const mapvglHeatmapLayerData = mapvglHeatmapDataShow.map((mapvglHeatmapData: MapvglHeatmapData) => {
        return {
            geometry: {
                type: 'Point',
                coordinates: [mapvglHeatmapData.lng, mapvglHeatmapData.lat]
            },
            properties: {
                count: mapvglHeatmapData.count,
            },
        };
    });
    mapvglHeatmapLayer.setData(mapvglHeatmapLayerData);
};
const drawMapvglHeatmapLayer = () => {

    const mapvglHeatmapOptions = {
        ...data.value.mapvglHeatmap.options,
    };

    if (mapvglView.getAllLayers().includes(mapvglHeatmapLayer)) {
        console.log('已经存在图层');
        // mapvglHeatmapLayer.options = mapvglHeatmapOptions;
    }
    else {
        mapvglHeatmapLayer = new mapvgl.HeatmapLayer({
            size: 20, // 单个点绘制大小
            max: 40, // 最大阈值
            height: 80, // 最大高度，默认为0
            unit: 'px', // 单位，m:米，px: 像素
            gradient: { // 对应比例渐变色
                0.25: 'rgba(89, 233, 179, 1)',
                0.55: 'rgba(182, 243, 147, 1)',
                0.85: 'rgba(254, 255, 140, 1)',
                0.9: 'rgba(217, 29, 28, 1)',
            }
        });
        // mapvglView.addLayer(mapvglHeatmapLayer);
    }
    // setMapvglHeatmapLayerData();



};
const setMapvglLayersData = () => {

    if (config.value.mapvgl.pointLayerShow && config.value.mapvgl.isDynamicPointLayers) {
        console.error('setPointLayer');
        setMapvglPointLayersData();
    }
    if (config.value.mapvgl.iconLayerShow && config.value.mapvgl.isDynamicIconLayers) {
        console.error('setIconLayer');
        setMapvglIconLayersData();
    }
    if (config.value.mapvgl.labelLayerShow && config.value.mapvgl.isDynamicLabelLayers) {
        console.error('setLabelLayer');
        setMapvglLabelLayersData();
    }
    if (config.value.mapvgl.heatmapLayerShow && mapvglHeatmapLayer && config.value.mapvgl.isDynamicHeatmapLayers) {
        console.error('setHeatMapLayer');
        setMapvglHeatmapLayerData();
    }
};
const clearMapvglCanvas = () => {
    mapvglView.removeAllLayers();
    const canvas = document.querySelector('canvas');
    const context = canvas?.getContext('webgl2');
    if (context) {
        const red = 1;
        const green = 0.5;
        const blue = 0.7;
        const alpha = 1;
        context.clearColor(red, green, blue, alpha);
        context.clear(context.COLOR_BUFFER_BIT);
        context.canvas.width = 0;
        context.canvas.height = 0;
    }
};

onBeforeMount(() => {
    // loadMap();
});

const isShow = ref(true);
const _setVisible = (s: boolean) => {
    isShow.value = s;
    if (s) {
        initMap();
    }
}

const refreshProps = (_config: any, _data: any, _callbacks: any) => {
    if (_config) {
        Object.assign(config.value, _config);
        // config.value = _config;
    }
    if (_data) {
        Object.assign(data.value, _data);
        // data.value = _data;
    }
    if (_callbacks) {
        Object.assign(callbacks.value, _callbacks);
        // callbacks.value = _callbacks;
    }
}

onMounted(() => {
    initMap();

    // 定义defineexpose 暴露  只针对ref getCurrentInstance() 获得的实例任然没有
    // 这里强制挂载
    const _this: any = getCurrentInstance()?.proxy;
    _this.setVisible = _setVisible;
    _this.Init = initMap;
    _this.RefreshProps = refreshProps;
    _this.DrawMapvglHeatmapLayer = drawMapvglHeatmapLayer;
    MapglMgr.Instance().setBaiduMapIns(_this);
});



onActivated(() => {
    // 若地图所在页面做了缓存，则在再次进入地图页面时，手动触发一次地图的移动，确保从地图所在页面跳转到其他页面之后，再返回地图所在页面时，地图上能正常回显跳转之前的mapvgl图层
    if (router.currentRoute.value.meta.keepAlive) {
        map.panBy(0, 0);
    }
});
onDeactivated(() => {

});
onBeforeUnmount(() => {
    // 手动清除mapvgl的canvas
    // clearMapvglCanvas()
});

defineExpose({
    map,
    mapvglView,
    isMultiFingerTouch,
    drawLabels,
    removeLabels,
    drawCircles,
    removeCircles,
});
</script>

<style lang="scss" scoped>
.map-container {
    // width: 100%;
    // height: 100%;
    width: 150%;
    height: 150%;
    position: absolute;
    top: -25%;
    left: -25%;
}
</style>
